package com.fare.taluo.application.impl.plane.city;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dayatang.domain.InstanceFactory;
import com.dayatang.querychannel.support.Page;
import com.fare.taluo.application.plane.city.CityQueryApplication;
import com.fare.taluo.application.plane.city.PortApplication;
import com.fare.taluo.base.ddd.application.BaseApplicationImpl;
import com.fare.taluo.core.domain.config.channel.SourceEntity;
import com.fare.taluo.core.domain.config.city.CityEntity;
import com.fare.taluo.core.domain.config.city.PortEntity;
import com.fare.taluo.core.domain.crawl.TaskTemplateEntity;
import com.fare.taluo.core.domain.crawl.TaskTemplateEntityRepository;
import com.fare.taluo.util.StringUtils;
import com.fare.taluo.vo.config.city.CityLineSelectVO;
import com.fare.taluo.vo.config.city.CitySelectVO;
import com.fare.taluo.vo.core.CityEntityVO;

@Scope("singleton")
@Service("cityQueryApplication")
public class CityQueryApplicationImpl extends BaseApplicationImpl implements CityQueryApplication {

	@Inject
	private PortApplication portApplication;
	@Override
	@Transactional(value="txManager")
	public List<CityEntityVO> findAll() {
		List<CityEntityVO> voList = new ArrayList<CityEntityVO>();
		List<CityEntity> entityList = new CityEntity().findAll();
		for (CityEntity CityEntity : entityList) {
			CityEntityVO vo = this.convert2VO(CityEntity);
			voList.add(vo);
		}	
		return voList;
	}
	
	private CityEntity covert2Entity(CityEntityVO vo) {
		CityEntity entity=new CityEntity();
		entity.setCode(vo.getCode());
		entity.setCreateDate(vo.getCreateDate());
		entity.setId(vo.getId());
		entity.setIsInternational(vo.getIsInternational());
		entity.setName(vo.getName());
		entity.setNameSpell(vo.getNameSpell());
		entity.setNameSpellInitials(vo.getNameSpellInitials());
		entity.setPid(vo.getPid());
		entity.setState(vo.getState());
		entity.setHotLevel(vo.getHotLevel());
		entity.setTreeLevel(vo.getTreeLevel());
		entity.setTreeSort(vo.getTreeSort());
		entity.setTreeType(vo.getTreeType());
		entity.setUpdateDate(vo.getUpdateDate());
		return entity;
	}
	
	private CityEntityVO convert2VO(CityEntity entity){
		CityEntityVO vo = new CityEntityVO();
		vo.setCode(entity.getCode());
		vo.setCreateDate(entity.getCreateDate());
		vo.setId(entity.getId());
		vo.setIsInternational(entity.getIsInternational());
		vo.setName(entity.getName());
		vo.setNameSpell(entity.getNameSpell());
		vo.setNameSpellInitials(entity.getNameSpellInitials());
		vo.setPid(entity.getPid());
		vo.setState(entity.getState());
		vo.setHotLevel(entity.getHotLevel());
		vo.setTreeTypeDesc(CityEntity.cityTypes.get(entity.getTreeType()));
		vo.setTreeLevel(entity.getTreeLevel());
		vo.setTreeSort(entity.getTreeSort());
		vo.setTreeType(entity.getTreeType());
		vo.setUpdateDate(entity.getUpdateDate());
		return vo;
	}

	@Override
	@Transactional(value="txManager")
	public CityEntityVO findByCityCode(String cityCode) {
		List<CityEntityVO> voList = new ArrayList<CityEntityVO>();
		List<CityEntity> entityList = new CityEntity().findCityEntityByCityCode(cityCode);
		for (CityEntity CityEntity : entityList) {
			CityEntityVO vo = this.convert2VO(CityEntity);
			voList.add(vo);
		}
		if(StringUtils.checkList(voList)){
			return voList.get(0);
		}else{
			return null;
		}
	}
	
	@Override
	@Transactional(value="txManager")
	public CityEntityVO findByPortCode(String airPortCode) {
		List<CityEntityVO> voList = new ArrayList<CityEntityVO>();
		List<CityEntity> entityList = new CityEntity().findCityEntityByCityCode(airPortCode);
		for (CityEntity CityEntity : entityList) {
			CityEntityVO vo = this.convert2VO(CityEntity);
			voList.add(vo);
		}
		if(StringUtils.checkList(voList)){
			return voList.get(0);
		}else{
			return null;
		}
	}
	@Override
	@Transactional(value="txManager")
	public void createCitySelect() {
		//获得所有的城市
		Map<String, PortEntity> portMaps = new PortEntity().findPortEntityToMap();
		//获得所有的机场
		Map<String, CityEntity> cityMaps = new CityEntity().findCityToMap();
		//获得所有的配置模板
		List<SourceEntity> channels = new SourceEntity().findCrawlAirCompany();
		//key:value 渠道：城市或机场选择框，key:list 城市或机场：对象集合
		Map<String, Map<String,List<CitySelectVO>>> map = new HashMap<String, Map<String,List<CitySelectVO>>>();
		//这个是按渠道的
		for(SourceEntity source :channels){
			List<TaskTemplateEntity> tasks = InstanceFactory.getInstance(TaskTemplateEntityRepository.class).findJDBCByHbaseKey(source.getHbaseKey());
			map.put(source.getHbaseKey(), this.convert2SelectCity(portMaps,cityMaps,tasks));
		}
		//这个是全部的,集合map过滤重复的
		map.put(CitySelectOper.ALL, this.allCityInfos(map));
		//动态创建ＪＳ文件
		new CitySelectOper(map).createJsFile();
	}
	/**
	 * 获得某个航空公司下的所有机场或城市信息
	 * @param hbasekey
	 * @return
	 */
	@Override
	@Transactional(value="txManager")
	public List<CityLineSelectVO> getCitysByChannel(String hbasekey){
		List<CityLineSelectVO> results = new ArrayList<CityLineSelectVO>();
		//获得所有的城市
		Map<String, PortEntity> portMaps = new PortEntity().findPortEntityToMap();
		//获得所有的机场
		Map<String, CityEntity> cityMaps = new CityEntity().findCityToMap();
		List<TaskTemplateEntity> tasks = InstanceFactory.getInstance(TaskTemplateEntityRepository.class).findJDBCByHbaseKey(hbasekey);
		
		Map<String,List<CitySelectVO>> maps = this.convert2SelectCity(portMaps,cityMaps,tasks);
		List<CitySelectVO> citySelects = maps.get(CitySelectOper.PORT);
		CityLineSelectVO vo = null;
		for(TaskTemplateEntity e : tasks){
			CitySelectVO fvo = getSelectCityVO(citySelects, e.getFromCity());
			CitySelectVO tvo = getSelectCityVO(citySelects, e.getToCity());
			//如果还没有配置在我们的城市机场结构中，不显示
			if(fvo == null || tvo == null) continue;
			//如果是国际城市暂不显示（随着业务发展才需要,目前国际的抓取没有单程等）
			//if(fvo.isInternation() || tvo.isInternation()) continue;
			vo = new CityLineSelectVO(hbasekey, null, fvo, tvo);
			if(!results.contains(vo)) results.add(vo);
		}
		return results;
	}
	
	@Override
	public int getCitysByChannelLines(String hbasekey) {
		int counts =0;
		counts=InstanceFactory.getInstance(TaskTemplateEntityRepository.class).findJDBCByHbaseKeys(hbasekey);
		return counts;
	}
	
	private CitySelectVO getSelectCityVO(List<CitySelectVO> citySelects , String cityCode){
		for(CitySelectVO vo : citySelects){
			if(vo.getCode().equalsIgnoreCase(cityCode)) return vo;
		}
		return null;
	}
	/**
	 * 所有的城市与机场
	 * @param map
	 * @return
	 */
	private Map<String, List<CitySelectVO>> allCityInfos(Map<String, Map<String,List<CitySelectVO>>> map){
		Map<String, List<CitySelectVO>> results = new HashMap<String, List<CitySelectVO>>();
		List<CitySelectVO> portSelects = new ArrayList<CitySelectVO>();
		List<CitySelectVO> citySelects = new ArrayList<CitySelectVO>();
		List<CitySelectVO> citys = null;
		List<CitySelectVO> ports = null;
		for(Map<String,List<CitySelectVO>> m : map.values()){
			citys = m.get(CitySelectOper.CITY);
			ports = m.get(CitySelectOper.PORT);
			for(CitySelectVO v : citys){
				if(!citySelects.contains(v)) citySelects.add(v);
			}
			for(CitySelectVO v : ports){
				if(!portSelects.contains(v)) portSelects.add(v);
			}
		}
		results.put(CitySelectOper.CITY, citySelects);
		results.put(CitySelectOper.PORT, portSelects);
		return results;
	}
	/**
	 * 不同渠道下的城市与机场
	 * @param map
	 * @return
	 */
	private Map<String, List<CitySelectVO>> convert2SelectCity(Map<String, PortEntity> portMaps, 
			Map<String, CityEntity> cityMaps
			, List<TaskTemplateEntity> tasks){
		Map<String, List<CitySelectVO>> results = new HashMap<String, List<CitySelectVO>>();
		List<String> codes = new ArrayList<String>();
		PortEntity port = null;
		CityEntity city = null;
		List<CitySelectVO> portSelects = new ArrayList<CitySelectVO>();
		List<CitySelectVO> citySelects = new ArrayList<CitySelectVO>();
		for(TaskTemplateEntity t : tasks){
			if(t.getFromCity()!=null && !codes.contains(t.getFromCity())){
				codes.add(t.getFromCity());
				port = portMaps.get(t.getFromCity());
				if(port != null) {//包括了机场，就一定会包含城市
					city = port.getCity();
					if(city != null){
						portSelects.add(new CitySelectVO(port.getId(),port.getCode(), port.getAliasName(), 
								city.getNameSpellInitials(), city.getNameSpell(),port.getHotlevel()>0,
							city.getIsInternational()==1));
						
						citySelects.add(new CitySelectVO(city.getId(), city.getCode(), city.getName(), 
								city.getNameSpellInitials(), city.getNameSpell(), city.getHotLevel()>0,
								city.getIsInternational()==1));
					}
				}else{//否则是城市
					city = cityMaps.get(t.getFromCity());
					if(city != null)
						citySelects.add(new CitySelectVO(city.getId(), city.getCode(), city.getAliasName(), 
								city.getNameSpellInitials(), city.getNameSpell(),city.getHotLevel()>0,
								city.getIsInternational()==1));
				}
			}
			if(t.getToCity() != null && !codes.contains(t.getToCity())){
				codes.add(t.getToCity());
				port = portMaps.get(t.getToCity()); 
				if(port != null) {//包括了机场，就一定会包含城市
					city = port.getCity();
					if(city != null){
						portSelects.add(new CitySelectVO(port.getId(), port.getCode(), port.getAliasName(), 
								city.getNameSpellInitials(), city.getNameSpell(),port.getHotlevel()>0,
							city.getIsInternational()==1));
						
						citySelects.add(new CitySelectVO(city.getId(), city.getCode(), city.getName(), 
								city.getNameSpellInitials(), city.getNameSpell(), city.getHotLevel()>0,
								city.getIsInternational()==1));
					}
				}else{//否则是城市
					city = cityMaps.get(t.getFromCity());
					if(city != null)
						citySelects.add(new CitySelectVO(city.getId(), city.getCode(), city.getAliasName(), 
								city.getNameSpellInitials(), city.getNameSpell(),city.getHotLevel()>0,
								city.getIsInternational()==1));
				}
			}
		}
		results.put(CitySelectOper.CITY, citySelects);
		results.put(CitySelectOper.PORT, portSelects);
		return results;
	}
	
	@Override
	@Transactional(value="txManager")
	public List<CityEntityVO> findByPid(Long pid) {
		List<CityEntity> results = super.queryChannel().queryResult("from CityEntity c where pid=? order by treeSort",new Object[]{pid});
		List<CityEntityVO> voList = new ArrayList<CityEntityVO>();
		for (CityEntity e : results) {
			voList.add(this.convert2VO(e));
		}
		return voList;
	}
	@Override
	@Transactional(value="txManager")
	public CityEntityVO findById(Long id) {
		CityEntity entity =new CityEntity();
		entity =entity.getCity(id);
		CityEntityVO vo =this.convert2VO(entity);
		return vo;
	}
	@Override
	@Transactional(value="txManager")
	public void saveOrUpdate(CityEntityVO vo) {
		CityEntity entity =new CityEntity();
		entity =this.covert2Entity(vo);
		if(null!=entity.getPid() && entity.getPid()>0){
			entity.setParent(entity.getCity(entity.getPid()));
		}
		entity.saveOrUpdate(entity);
	}
	

	@Override
	@Transactional(value="txManager")
	public void delete(CityEntityVO vo) {
		CityEntity entity =new CityEntity();
		entity =this.covert2Entity(vo);
		entity.delete(entity);
	}

	@Override
	@Transactional(value="txManager")
	public Page<CityEntityVO> pageQuery(Long pid, int currentPage, int pageSize) {
		Page<CityEntity> results = super.queryChannel().queryPagedResultByPageNo("from CityEntity c where pid=? order by treeSort",new Object[]{pid},currentPage, pageSize);
		List<CityEntityVO> list =new ArrayList<CityEntityVO>();
		for(CityEntity entity:results.getResult()){
			CityEntityVO vo =this.convert2VO(entity);
			list.add(vo);
		}
		return new Page<CityEntityVO>(results.getCurrentPageNo(), results.getTotalCount(), results.getPageSize(), list);
	}

	@Override
	@Transactional(value="txManager")
	public List<String> getAllPortsByCity(String cityCode) {
		List<String> codes = new ArrayList<String>();
		codes.add(cityCode);
		List<CityEntity> citys = new CityEntity().findCityEntityByCityCode(cityCode);
		PortEntity port = new PortEntity();
		if(citys != null && !citys.isEmpty()){
			for(CityEntity e : citys){
				for(PortEntity pe : port.findPortEntityByCityCode(e.getCode())){
					codes.add(pe.getCode());
				}
			}
		}
		return codes;
	}


}
